package com.lh0811.forge.pserv.uacs.server.adapter.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.lh0811.forge.dependency.basic_code.ListToTreeUtil;
import com.lh0811.forge.dependency.basic_web.constant.AuthConstant;
import com.lh0811.forge.dependency.basic_web.response.ServerResponse;
import com.lh0811.forge.dependency.security.client.component.SecurityUtil;
import com.lh0811.forge.dependency.security.client.component.annotation.TokenToAuthority;
import com.lh0811.forge.dependency.security.core.model.entity.SecurityAuthority;
import com.lh0811.forge.dependency.security.core.model.entity.SecurityMenu;
import com.lh0811.forge.dependency.security.core.token.TokenManager;
import com.lh0811.forge.pserv.uacs.api.param.*;
import com.lh0811.forge.pserv.uacs.api.vo.CurrentUacsUserInfoVo;
import com.lh0811.forge.pserv.uacs.api.vo.TDesignMenu;
import com.lh0811.forge.pserv.uacs.server.config.auth.VerificationHandler;
import com.lh0811.forge.pserv.uacs.server.repository.dao.UacsPlateUserDao;
import com.lh0811.forge.pserv.uacs.server.repository.entity.UacsPlateUser;
import com.lh0811.forge.pserv.uacs.server.service.CurrentUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author lh0811
 * @date 2021/5/23
 */
@Slf4j
@Tag(name = "权限中心-通用接口")
@RestController
@RequestMapping("/forge/plate/v1/uacs/curr_user")
public class CommCurrentUserController {

    @Resource
    private CurrentUserService currentUserService;

    @Resource
    private TokenManager tokenManager;

    @Resource
    private UacsPlateUserDao uacsPlateUserDao;

    @Resource
    private VerificationHandler verificationHandler;

    // 平台用户注册
    @PutMapping("/register")
    @Operation(summary = "平台用户注册")
    public ServerResponse plateUserRegister(@RequestBody @Valid UacsPlateUserRegisterParam param) throws Exception {
        currentUserService.plateUserRegister(param);
        return ServerResponse.createBySuccess("注册成功");
    }

    // 当前用户信息
    @TokenToAuthority
    @GetMapping("/current_user/info")
    @Operation(summary = "当前用户信息", parameters = {
            @Parameter(in = ParameterIn.HEADER, name = AuthConstant.TokenKey, description = "用户Token")
    })
    public ServerResponse<CurrentUacsUserInfoVo> getCurrentUserInfo() throws Exception {
        return ServerResponse.createBySuccess(currentUserService.getCurrentUserInfo());
    }

    @TokenToAuthority
    @PostMapping("/change_tenant")
    @Operation(summary = "切换租户信息", parameters = {
            @Parameter(in = ParameterIn.HEADER, name = AuthConstant.TokenKey, description = "用户Token")
    })
    public ServerResponse changeTenantInfo(@RequestBody ChangeTenantInfoParam param) throws Exception {
        currentUserService.changeTenantInfo(param.getTenantId());
        return ServerResponse.createBySuccess();
    }


    // 用户菜单信息
    @TokenToAuthority
    @GetMapping("/user/menu")
    @Operation(summary = "用户菜单信息", parameters = {
            @Parameter(in = ParameterIn.HEADER, name = AuthConstant.TokenKey, description = "用户Token")
    })
    public ServerResponse<List<SecurityMenu>> userMenuTree() throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        return ServerResponse.createBySuccess(securityAuthority.getSecurityUser().getMenuTreeList());
    }

    // 用户菜单信息
    @TokenToAuthority
    @GetMapping("/user/menu/t_design")
    @Operation(summary = "用户菜单信息(TDesign)", parameters = {
            @Parameter(in = ParameterIn.HEADER, name = AuthConstant.TokenKey, description = "用户Token")
    })
    public ServerResponse<List<TDesignMenu>> userMenuTreeTDesign() throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        List<SecurityMenu> menuList = securityAuthority.getSecurityUser().getMenuList();
        List<TDesignMenu> tDesignMenuList = Lists.newArrayList();
        for (SecurityMenu securityMenu : menuList) {
            TDesignMenu tDesignMenu = new TDesignMenu();
            tDesignMenu.setId(securityMenu.getId());
            tDesignMenu.setPid(securityMenu.getPid());
            tDesignMenu.setPath(securityMenu.getUrl()); // 路径
            tDesignMenu.setName(securityMenu.getResName()); // 资源名称
//            tDesignMenu.setRedirect(securityMenu.getUrl()); // 地址
            tDesignMenu.setChildren(Lists.newArrayList());

            // 元数据配置
            JSONObject metaObj = JSON.parseObject(securityMenu.getMeta());
            JSONObject titleObj = metaObj.getJSONObject("title");

            TDesignMenu.Meta meta = new TDesignMenu.Meta();
            meta.setTitle(new TDesignMenu.Title(titleObj.getString("zh_CN"), titleObj.getString("en_US")));
            meta.setIcon(metaObj.getString("icon"));
            meta.setLayout(metaObj.getString("layout"));
            meta.setFrameSrc(metaObj.getString("frameSrc"));
            tDesignMenu.setMeta(meta);

            tDesignMenu.setComponent(metaObj.getString("component")); // 布局组件
            if (StringUtils.isNotBlank(metaObj.getString("name"))) {
                tDesignMenu.setName(metaObj.getString("name"));
            }

            if (StringUtils.equalsIgnoreCase("IFrame", metaObj.getString("layout"))) {
                tDesignMenu.setComponent("IFRAME");
            }
            tDesignMenuList.add(tDesignMenu);
        }

        List<TDesignMenu> tDesignMenuTree = ListToTreeUtil.listToTree(tDesignMenuList, "0", "pid", "id", "children").toJavaList(TDesignMenu.class);

        return ServerResponse.createBySuccess(tDesignMenuTree);
    }

    // 补充平台用户信息
    @TokenToAuthority
    @PostMapping("/plate_user/fill/info")
    @Operation(summary = "补充平台用户信息", parameters = {
            @Parameter(in = ParameterIn.HEADER, name = AuthConstant.TokenKey, description = "用户Token")
    })
    public ServerResponse fillPlateUserInfo(@RequestBody @Valid UacsPlateUserFillInfoParam param) throws Exception {
        currentUserService.fillPlateUserInfo(param);
        return ServerResponse.createBySuccess();
    }

    // 用户实名认证
    @TokenToAuthority
    @PostMapping("/user/real_name/auth")
    @Operation(summary = "用户实名认证", parameters = {
            @Parameter(in = ParameterIn.HEADER, name = AuthConstant.TokenKey, description = "用户Token")
    })
    public ServerResponse userRealNameAuthentication(@RequestBody @Valid UserRealNameAuthenticationParam param) throws Exception {
        currentUserService.userRealNameAuthentication(param);
        return ServerResponse.createBySuccess();
    }

    // 判断用户是否绑定手机号
    @TokenToAuthority
    @GetMapping("/user/building/phone/check")
    @Operation(summary = "判断用户是否绑定手机号", parameters = {
            @Parameter(in = ParameterIn.HEADER, name = AuthConstant.TokenKey, description = "用户Token")
    })
    public ServerResponse<Boolean> checkUserBuildingPhone() throws Exception {
        return ServerResponse.createBySuccess(currentUserService.checkUserBuildingPhone());
    }

    // 判断用户是否已经实名认证
    @TokenToAuthority
    @GetMapping("/user/building/real_name/check")
    @Operation(summary = "判断用户是否已经实名认证", parameters = {
            @Parameter(in = ParameterIn.HEADER, name = AuthConstant.TokenKey, description = "用户Token")
    })
    public ServerResponse<Boolean> checkUserRealNameAuth() throws Exception {
        return ServerResponse.createBySuccess(currentUserService.checkUserRealNameAuth());
    }

    @TokenToAuthority
    @PostMapping("/reset/pwd")
    @Operation(summary = "重置密码", parameters = {
            @Parameter(in = ParameterIn.HEADER, name = AuthConstant.TokenKey, description = "用户Token")
    })
    public ServerResponse reSetPassword(@Valid @RequestBody ReSetPasswordParam param) throws Exception {
        currentUserService.reSetPassword(param);
        return ServerResponse.createBySuccess();
    }


    /**
     * 切换当前用户所在租户
     */
    @TokenToAuthority
    @GetMapping("/change/tenant")
    @Operation(summary = "切换当前用户所在租户", parameters = {
            @Parameter(in = ParameterIn.HEADER, name = AuthConstant.TokenKey, description = "用户Token")
    })
    public ServerResponse<String> changeUserTenant(@RequestParam(value = "tenantId") Long tenantId) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsPlateUser uacsPlateUser = uacsPlateUserDao.getById(Long.valueOf(securityAuthority.getUserId()));
        SecurityAuthority userTenantSecurityAuthority = verificationHandler.getUserTenantSecurityAuthority(uacsPlateUser, tenantId);
        String token = tokenManager.tokenGenerateAndSave(userTenantSecurityAuthority);
        return ServerResponse.createBySuccess("成功", token);
    }

}
